package com.ls.fw.data.search.impl.solrj.maker;

import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.solr.client.solrj.response.Group;
import org.apache.solr.client.solrj.response.GroupCommand;
import org.apache.solr.client.solrj.response.GroupResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ls.fw.data.bean.Column;
import com.ls.fw.data.bean.MethodField;
import com.ls.fw.data.bean.Record;
import com.ls.fw.data.dao.DataDaoConstant;
import com.ls.fw.data.enums.AFunctions;
import com.ls.fw.data.result.DataResult;
import com.ls.fw.data.result.DataResultSet;
import com.ls.fw.data.search.impl.solrj.domain.Constant;
import com.ls.fw.data.statement.Select;
import com.ls.fw.data.utils.IDHander;

public class DataResultMaker {
	
	protected static Logger logger = LoggerFactory.getLogger(DataResultMaker.class);
	private static final List<String> exceptField = new ArrayList<String>();
	static{
		exceptField.add(Constant.VERSION_FILED);
		exceptField.add(Constant.SCORE_FILED);
	}
	private static final List<String> exceptPrefixField = new ArrayList<String>();
	static{
		exceptPrefixField.add(DataDaoConstant.SYSTEM_FIELD_PREFIXX);
		
	}
	
	public static Record makeRecord(DataResultSet resultSet,String priKeyName) throws SQLException{
		Record  record = null;
		record = new Record();
		ResultSetMetaData  metaData = resultSet.getMetaData();
		int columnCount = metaData.getColumnCount();
		int index = 0;
		while(columnCount>index){
			String name = metaData.getColumnName(index+1);
			Object value = resultSet.getObject(index);
			if (name.equals(priKeyName)) {
				String id = IDHander.resloveValue(String.valueOf(value));
				record.addField(name, id);
			}else{
				record.addField(name, value);
			}
			index++;
		}
		record.setSchemaName(resultSet.getSchemaName());
		record.setTable(resultSet.getTable());
		record.setVersion(resultSet.getVersion());
		record.setScore(resultSet.getScore());
		return record;
	}
	
	
	/**
	 * 处理查询结果
	 * @author ls
	 * 2014年11月22日下午4:14:26 
	 * @param dlist
	 * @param select
	 * @return
	 */
	public static DataResult makeResult(final SolrDocumentList dlist
			, final Select select, final String priKeyName){
		
		List<Column> list = null;
		if(select!=null){
			 list = select.getFields();
		}
		boolean showAll = false, isAgg = false;
		Column column = null;
		if(list !=null && !list.isEmpty()){
			int index = list.size();
			if(index==1){
				column = list.get(0);
				if (column instanceof MethodField) {
					 isAgg = true;
				}else{
					if(column.isShowAll()){
						showAll = true;
					}
				}
			}
		}else{
			showAll = true;
		}
		DataResult result = new DataResult(dlist.getNumFound());
		result.setMaxScore(dlist.getMaxScore());
		if(!isAgg){
			result = handlResult(result,dlist, showAll, list, priKeyName);
		}else{
			result.add(handlAggRecord(dlist, column));
		}
		return result;
	}

	
	/**
	 * 处理聚合函数结果
	 * @author ls
	 * 2014年11月24日下午2:36:09 
	 * @param record
	 * @param dlist
	 * @param column
	 * @return
	 */
	private static Record handlAggRecord(final Record  record, final SolrDocumentList dlist, final Column column){
		AFunctions af =	AFunctions.get(column.getName());
		switch(af){
			case AVG:
				break;
			case COUNT:
				record.addField(column.getName(), dlist.getNumFound());
				break;
			case MAX:
				break;
			case MIN:
				break;
			case SUM:
				break;
			case UNKWON:
			default:
				break;
		}
		return record;
	}
	
	/**
	 * 处理聚合函数结果
	 * @author ls
	 * 2014年11月24日下午2:36:27 
	 * @param dlist
	 * @param column
	 * @return
	 */
	private static Record handlAggRecord(final SolrDocumentList dlist, final Column column){
		Record  record = null;
		record = new Record();
		return handlAggRecord(record, dlist, column);
	}

	 
	/**
	 * 处理结果
	 * @author ls
	 * 2014年11月24日下午2:36:31 
	 * @param result
	 * @param dlist
	 * @param showAll
	 * @param list
	 * @return
	 */
	private static DataResult handlResult(final DataResult result, final SolrDocumentList dlist
			, final boolean showAll, final List<Column> list, final String priKeyName){
		final List<String> fields = new ArrayList<String>();
		for (SolrDocument solrDocument : dlist) {
			result.add(handRecord(solrDocument, showAll, list, fields,priKeyName));
		}
		fields.clear();
		return result;
	}
	
	private static boolean isExcept(String name){
		for (String string : exceptField) {
			if(string.equals(name)){
				return true;
			}
		}
		for (String string : exceptPrefixField) {
			if(name.startsWith(string)){
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 处理单条记录结果
	 * @author ls
	 * 2014年11月24日下午2:36:40 
	 * @param solrDocument
	 * @param showAll
	 * @param list
	 * @return
	 */
	private static Record handRecord(final SolrDocument solrDocument
			, final boolean showAll, final List<Column> list
			, final List<String> fields , final String priKeyName){
		Record  record = null;
		record = new Record();
		Object value = null;
		if(showAll){
			if(fields.isEmpty()){
				Collection<String> names = solrDocument.getFieldNames();
				for (String name : names) {
					if(!isExcept(name)){
						value = solrDocument.getFieldValue(name);
						if (name.equals(priKeyName)) {
							String id = IDHander.resloveValue(String.valueOf(value));
							record.addField(name, id);
						}else{
							record.addField(name, value);
						}
						fields.add(name);
					}
				}
			}else{
				for (String name : fields) {
					value = solrDocument.getFieldValue(name);
					if (name.equals(priKeyName)) {
						String id = IDHander.resloveValue(String.valueOf(value));
						record.addField(name, id);
					}else{
						record.addField(name, value);
					}
				}
			}
		}else{
			for (Column f : list) {
				String name = f.getName();
				value = solrDocument.getFieldValue(name);
				if (name.equals(priKeyName)) {
					String id = IDHander.resloveValue(String.valueOf(value));
					record.addField(f.getAlias(), id);
				}else{
					record.addField(f.getAlias(), value);
				}
			}
		} 
		if(solrDocument.containsKey(Constant.VERSION_FILED)){
			record.setVersion(Long.valueOf(String.valueOf(solrDocument.getFieldValue(Constant.VERSION_FILED))));
		}
		if(solrDocument.containsKey(Constant.SCORE_FILED)){
			record.setScore(Float.valueOf(String.valueOf(solrDocument.getFieldValue(Constant.SCORE_FILED))));
		}
		if (solrDocument.containsKey(DataDaoConstant.DEFAULT_TABLE_FIELD)) {
			value = solrDocument.getFieldValue(DataDaoConstant.DEFAULT_TABLE_FIELD);
			String t = String.valueOf(value);
			String[] ts = t.split("_");
			if(ts.length==2){
				record.setSchemaName(ts[0]);
				record.setTable(ts[1]);
			}
		}
		return record;
	}
	
	
	/**
	 * 处理分组结果
	 * @author ls
	 * 2014年11月24日下午1:23:26 
	 * @param groupResponse
	 * @param select
	 * @return
	 */
	public static DataResult makeGroupResult(final GroupResponse groupResponse
			, final Select select, final String priKeyName){
		DataResult result = new DataResult(); 
		final List<GroupCommand> groupCommandList = groupResponse.getValues();  
		final List<Column> list = select.getFields();
		boolean showAll = false;
		if(list !=null && !list.isEmpty()){
			int index = list.size();
			if(index==1){
				Column column = list.get(0);
				if (!(column instanceof MethodField)) {
					if(column.isShowAll()){
						showAll = true;
					}
				}
			}
		}else{
			showAll = true;
		}
        for (GroupCommand groupCommand : groupCommandList) {  
//        	System.out.println("GroupCommand Name : " + groupCommand.getName());  
//            System.out.println("Num of Groups Found: " + groupCommand.getNGroups());  
//            System.out.println("Num of documents Found: " + groupCommand.getMatches());  
//
//            System.out.println("The groups are: ");  
        	result.setTotal(groupCommand.getNGroups());
            List<Group> groups = groupCommand.getValues();  
            Record  record = null;
            for (Group group : groups) {  
                SolrDocumentList dlist = group.getResult();  
                /*System.out.println("group value: " + group.getGroupValue());  
                System.out.println("solrDocumentList.size():"+solrDocumentList.size());
                System.out.println("Num of Documents in this group: " + solrDocumentList.getNumFound());  
                System.out.println("start: " + solrDocumentList.getStart());  
                System.out.println("Max score: " + solrDocumentList.getMaxScore()); */
        		record = new Record();
                if(select.isAgg){
                	for (Column column : list) {
                		handlAggRecord(record,dlist, column);
                	}
                	result.add(record);
                }else{
                	handlResult(result,dlist, showAll, list, priKeyName);
                }
            }
            //目前只支持单个分组条件
            break;
        }
        return result;
	}
 
}
